/*#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"system.h"
#include "y.tab.h"*/
// int INTEGER=50,KEYWORD=100;

struct SymTableNode *CreateNewSymTableNode()
{
  int i=0;
  struct SymTableNode *t;
  t =(struct SymTableNode *)malloc(sizeof(struct SymTableNode));
  t->scope=0;
  t->next=NULL;
  for(i=0;i<HashSize;i++)
    t->table[i] = NULL;	
  return t;
}

struct SymEntry* lookup(char *name,int internalScope)
{
  struct SymEntry *r,*s;
  r=NULL;
  struct SymTableNode *temp;
  temp=global;
  int i=0,k=name[0]%HashSize,BiggestScopeFound=-1;  //Biggest Scope found less than or equal to internalScope.
  while(temp->next!=NULL)
  {  
    //printf("\nLooking in Scope %d\n",temp->scope);
    BiggestScopeFound=-1;
    s=temp->table[k];   
    if(s!=NULL)
    {
      if(strcmp(s->id,name)==0 && s->scope<=internalScope && BiggestScopeFound<=s->scope)
      {
	BiggestScopeFound=s->scope;
	r=s;
	//printf("\n---___--__--__--__UU--___--__--- %s Scope %d\n",s->id,s->scope);
      }    
      else
      {	
	while(s->next!=NULL)
	{
	  s=s->next;
	  //printf("\n---___--__--__--__--___--__--- %s Scope %d\n",s->id,s->scope);
	  if(strcmp(s->id,name)==0&& s->scope<=internalScope && BiggestScopeFound<=s->scope)
	  {
	    BiggestScopeFound=s->scope;
	    r=s;
	    break;
	  }
	}
      }      
    }    
    temp=temp->next;
  } 
  BiggestScopeFound=-1;
  s=temp->table[k];  
  //printf("\nEntering 2nd while loop\n");
  if(s!=NULL)
  {
    //printf("\nLooking in Scope %d\n",temp->scope);
    if(strcmp(s->id,name)==0&& s->scope<=internalScope && BiggestScopeFound<=s->scope)
      {
	BiggestScopeFound=s->scope;
      r=s;
      //printf("\n---___--__--__--__-UU-___--__--- %s Scope %d\n",s->id,s->scope);
    }    
    else
    {      
      while(s->next!=NULL)
      {
	s=s->next;
	//printf("\n---___--__--__--__--___--__--- %s Scope %d\n",s->id,s->scope);
	if(strcmp(s->id,name)==0&& s->scope<=internalScope && BiggestScopeFound<=s->scope)
	{
	  BiggestScopeFound=s->scope;
	  r=s;
	  break;
	}
      }
    }  
  }  
  //printf("\nSearch Finished\n");
  return r;
}
struct SymEntry *InsertSymTable(char *name,int currentScope,int typ,int internalScope)
{
  if(tail->scope!=currentScope)
  {
    printf("\n ( IN SYMTABLE.C )NewScope : %d.\n",currentScope);
    struct SymTableNode *temp;
    temp=CreateNewSymTableNode();
    temp->scope=tail->scope+1;	
    tail->next=temp;
    tail=temp;
  }
  struct SymEntry *p;
  p= (struct SymEntry *)malloc(sizeof(struct SymEntry));
  p->id=(char *)malloc(sizeof(char)*strlen(name)+1);
  strcpy(p->id,name);
  p->scope=internalScope;
  p->type=typ;
  p->next=tail->table[name[0]%HashSize];
  tail->table[name[0]%HashSize]=p;    
  return p;
}

void InitializeSymTable(int KEYWORD)
{
  global=CreateNewSymTableNode();
  tail=global;
  struct SymEntry *p;
  printf("Global created.\n");
  p=InsertSymTable("auto",0,KEYWORD,1);
  p->keywordval=AUTO;  
  //printf("Inserted auto,name : %s , value : %d\n",p->id,p->keywordval);
  p=InsertSymTable("break",0,KEYWORD,1);
  p->keywordval=BREAK;
  p=InsertSymTable("case",0,KEYWORD,1);
  p->keywordval=CASE;
  p=InsertSymTable("char",0,KEYWORD,1);
  p->keywordval=CHAR;
  p=InsertSymTable("const",0,KEYWORD,1);
  p->keywordval=CONST;
  p=InsertSymTable("continue",0,KEYWORD,1);
  p->keywordval=CONTINUE;
  p=InsertSymTable("default",0,KEYWORD,1);
  p->keywordval=DEFAULT;
  p=InsertSymTable("do",0,KEYWORD,1);
  p->keywordval=DO;
  p=InsertSymTable("double",0,KEYWORD,1);
  p->keywordval=DOUBLE;
  p=InsertSymTable("else",0,KEYWORD,1);
  p->keywordval=ELSE;
  p=InsertSymTable("enum",0,KEYWORD,1);
  p->keywordval=ENUM;
  p=InsertSymTable("extern",0,KEYWORD,1);
  p->keywordval=EXTERN;
  p=InsertSymTable("float",0,KEYWORD,1);
  p->keywordval=FLOAT;
  p=InsertSymTable("for",0,KEYWORD,1);
  p->keywordval=FOR;
  p=InsertSymTable("goto",0,KEYWORD,1);
  p->keywordval=GOTO;
  p=InsertSymTable("if",0,KEYWORD,1);
  p->keywordval=IF;
  p=InsertSymTable("int",0,KEYWORD,1);
  p->keywordval=INT;
  p=InsertSymTable("long",0,KEYWORD,1);
  p->keywordval=LONG;
  p=InsertSymTable("register",0,KEYWORD,1);
  p->keywordval=REGISTER;
  p=InsertSymTable("return",0,KEYWORD,1);
  p->keywordval=RETURN;
  p=InsertSymTable("short",0,KEYWORD,1);
  p->keywordval=SHORT;
  p=InsertSymTable("signed",0,KEYWORD,1);
  p->keywordval=SIGNED;
  p=InsertSymTable("sizeof",0,KEYWORD,1);
  p->keywordval=SIZEOF;
  p=InsertSymTable("static",0,KEYWORD,1);
  p->keywordval=STATIC;
  p=InsertSymTable("struct",0,KEYWORD,1);
  p->keywordval=STRUCT;
  p=InsertSymTable("switch",0,KEYWORD,1);
  p->keywordval=SWITCH;
  p=InsertSymTable("typedef",0,KEYWORD,1);
  p->keywordval=TYPEDEF;
  p=InsertSymTable("union",0,KEYWORD,1);
  p->keywordval=UNION;
  p=InsertSymTable("unsigned",0,KEYWORD,1);
  p->keywordval=UNSIGNED;
  p=InsertSymTable("void",0,KEYWORD,1);
  p->keywordval=VOID;
  p=InsertSymTable("volatile",0,KEYWORD,1);
  p->keywordval=VOLATILE;
  p=InsertSymTable("while",0,KEYWORD,1);
  p->keywordval=WHILE;
}
void PopSym()
{
  struct SymTableNode* temp;
  temp=global;
  while(temp->next->next!=NULL)
  {
      temp=temp->next;
  }
  temp->next=NULL;
  free(tail);
  tail=temp;
}
void PrintSymTable()
{
  printf("\nPrinting Symbol Table :\n");
  struct SymEntry *s;
  struct SymTableNode *temp;
  temp=global;
  int i=0;  //Biggest Scope found less than or equal to internalScope.
  while(temp->next!=NULL)
  {  
      printf("\nLooking in Node Scope %d\n",temp->scope);    
      for(i=0;i<HashSize;i++)
      {
	  s=temp->table[i];   	  
	  if(s!=NULL)
	  {
	    PrintSymEntry(s);	      	  
	    while(s->next!=NULL)
	    {
	      s=s->next;
	      PrintSymEntry(s);
	    }
	    //printf("\n00000000000000000000000000000000000000000\n");
	  }  
      }    
      temp=temp->next;
  }
  printf("\nLooking in Node Scope %d\n",temp->scope);    
  for(i=0;i<HashSize;i++)
  {
      s=temp->table[i];   
      if(s!=NULL)
      {
	PrintSymEntry(s);      
	while(s->next!=NULL)
	{
	  s=s->next;
	  PrintSymEntry(s);
	}
      }  
  }      
  //printf("\nSearch Finished\n");  
}
/*void PopSym()
{
  SymTableNode* temp=global;
  while(temp->next->!=NULL)
  {
      temp=temp->next;
  }
  temp->next=NULL;
  free(tail);
  tail=temp;
}*/

/*int main()
{
  struct SymEntry *p;
  printf("You are in.\n");
  InitializeSymTable(1);  
  printf("Global Node bana.\n");
  InsertSymTable("ABC1",1,1111,1);//INTEGER);
  
  p=lookup("ABC1",2);  
  //p=global->next->table[2];
  printf("Searched for ABC1.Tail ka scope : %d\n",tail->scope);
  if(p==NULL)
    printf("Variable ABC1 not found.\n");
  else printf("Variable found.Name : %s, Type : %d , Scope : %d, Value : %d\n",p->id,p->type,p->scope,p->keywordval);
  
  printf("ABC1hmm inserted.\n");
  InsertSymTable("ABC2",1,2222,1);//FLOAT,(void *)"10.910");
  InsertSymTable("ABC1",1,11191,2);//INTEGER);
  printf("ABC2 inserted.\n");
  InsertSymTable("BBC3",2,3333,1);//"POINTER TO CHAR",(void *)"asdad");
  InsertSymTable("ABC1",2,111221,1);
  printf("BBC3 inserted.\n");
  
  p=lookup("BBC3",1);  
  //p=global->next->table[2];
  printf("Searched for BBC3.Tail ka scope : %d\n",tail->scope);
  if(p==NULL)
    printf("Variable BBC3 not found.\n");
  else printf("Variable found.Name : %s, Type : %d , Scope : %d, Value : %d\n",p->id,p->type,p->scope,p->keywordval);
  
  p=lookup("ABC1",2);  
  //p=global->next->table[2];
  printf("Searched for ABC1.Tail ka scope : %d\n",tail->scope);
  if(p==NULL)
    printf("Variable ABC1 not found.\n");
  else printf("Variable found.Name : %s, Type : %d , Scope : %d, Value : %d\n",p->id,p->type,p->scope,p->keywordval);
  
  
  PopSym();
  p=lookup("BBC3",2);  
  //p=global->next->table[2];
  printf("Searched for BBC3.Tail ka scope : %d\n",tail->scope);
  if(p==NULL)
    printf("Variable BBC3 not found.\n");
  else printf("Variable found.Name : %s, Type : %d , Scope : %d, Value : %d\n",p->id,p->type,p->scope,p->keywordval);
  
  p=lookup("ABC1",2);  
  //p=global->next->table[2];
  printf("Searched for ABC1.Tail ka scope : %d\n",tail->scope);
  if(p==NULL)
    printf("Variable ABC1 not found.\n");
  else printf("Variable found.Name : %s, Type : %d , Scope : %d, Value : %d\n",p->id,p->type,p->scope,p->keywordval);
}*/
